package com.hcb.logsdk.service;

import android.content.Context;
import android.os.Handler;
import android.util.Log;

import com.hcb.logsdk.manager.LOGSDKManager;
import com.hcb.logsdk.manager.schedulerTask.CheckSocketConnectScheduledExecutor;
import com.hcb.logsdk.socketio.listener.IConstants;
import com.hcb.logsdk.socketio.listener.IEmitterListener;
import com.hcb.logsdk.socketio.listener.SocketPushDataListener;
import com.hcb.logsdk.socketio.socket.AppSocket;
import com.hcb.logsdk.util.BroadcastUtil;
import com.hcb.logsdk.util.C;
import com.hcb.logsdk.util.DeviceUtil;
import com.hcb.logsdk.util.L;

import java.util.concurrent.TimeUnit;

import io.socket.client.Manager;
import io.socket.client.Socket;

import static com.hcb.logsdk.manager.LOGSDKManager.API_URL;


/**
 * @author WangGuoWei
 * @time 2018/1/5 17:59
 * @des ${TODO}
 * <p>
 * ┽
 * ┽                            _ooOoo_
 * ┽                           o8888888o
 * ┽                           88" . "88
 * ┽                           (| -_- |)
 * ┽                           O\  =  /O
 * ┽                        ____/`---'\____
 * ┽                      .'  \\|     |//  `.
 * ┽                     /  \\|||  :  |||//  \
 * ┽                    /  _||||| -:- |||||-  \
 * ┽                    |   | \\\  -  /// |   |
 * ┽                    | \_|  ''\---/''  |   |
 * ┽                    \  .-\__  `-`  ___/-. /
 * ┽                  ___`. .'  /--.--\  `. . __
 * ┽               ."" '<  `.___\_<|>_/___.'  >'"".
 * ┽              | | :  `- \`.;`\ _ /`;.`/ - ` : | |
 * ┽              \  \ `-.   \_ __\ /__ _/   .-` /  /
 * ┽         ======`-.____`-.___\_____/___.-`____.-'======
 * ┽                            `=---='
 * ┽         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 * ┽                      佛祖保佑       永无BUG
 * ┽
 * ┽
 * ┽
 * @updateAuthor $Author$
 * @updateDate $Date$
 * @updateDes ${TODO}
 */
 public class PushServerConnection  implements IEmitterListener {
    private static final String LOGTAG = "PushLogService";
    Context ctx;
    private Handler mHandler = new Handler();
    private LOGSDKManager sdkManager;

    private boolean isTaskRuning = false;

    public PushServerConnection(Context ctx) {
        this.ctx = ctx;
        checkSocketConect();
    }

    private void checkSocketConect() {
        checkSocketConnectScheduledTask();
    }

    public SocketPushDataListener mListener;
    public void setSocketPushDataListener(SocketPushDataListener mListener){
        this.mListener = mListener;
    }
    public void setSocketPushDataListener(){
    }
    public void setSDKManager(LOGSDKManager sdkManager){
        this.sdkManager = sdkManager;
    }

    //子线程
    @Override
    public void emitterListenerResut(String key, Object... args) {
        switch (key) {
            case Manager.EVENT_TRANSPORT:

                break;

            case Socket.EVENT_CONNECT_ERROR:
                Log.i(LOGTAG, "EVENT_CONNECT_ERROR");
                break;

            case Socket.EVENT_CONNECT_TIMEOUT:
                Log.i(LOGTAG, "EVENT_CONNECT_TIMEOUT");
                break;

            // Socket连接成功
            case Socket.EVENT_CONNECT:
                L.isConnected = true;
                C.SOCKET_CONNECT_COUNT = 0;

                BroadcastUtil.sendBroadcastToUI(ctx, IConstants.LOG_EVENT_CONNECT,"Socket连接成功!!!");

                Log.i(LOGTAG, "Socket连接成功");

                if(!isTaskRuning)
                    return;
                mHandler.removeCallbacksAndMessages(null);
                isTaskRuning = false;
                break;

            // Socket断开连接
            case Socket.EVENT_DISCONNECT:
                offEmitterListener();
                L.isConnected = false;
                BroadcastUtil.sendBroadcastToUI(ctx, IConstants.LOG_EVENT_DISCONNECT,"Socket断开连接!!!");
                break;

            // Socket连接错误
            case Socket.EVENT_ERROR:
                Log.i(LOGTAG, "EVENT_ERROR");
                break;

            // Socket重新连接
            case Socket.EVENT_RECONNECT:
                break;

            case Socket.EVENT_RECONNECT_ATTEMPT:
                Log.i(LOGTAG, "EVENT_RECONNECT_ATTEMPT");
                if(isTaskRuning)
                    return;

                Log.i(LOGTAG, "Socket试图重新连接,执行延时连接任务--------------");
                 mHandler.postDelayed(new Runnable() {//将Runnable发送到Handler所在线程（一般是主线程）的消息队列中
                    @Override
                    public void run() {

                        if(L.isConnected){
                            Log.i("PushService", "Socket已经连接！！！--------------");
                            return;
                        }

                        //开始连接
                        sdkManager.startconnect();
                        isTaskRuning = false;
                        Log.i(LOGTAG, "开始执行延时连接任务--------------");
                    }
                },(5*60*1000)+(10*1000));
                isTaskRuning = true;
                break;

            case Socket.EVENT_RECONNECT_ERROR:
                Log.i(LOGTAG, "EVENT_RECONNECT_ERROR");
                break;

            case Socket.EVENT_RECONNECT_FAILED:
                Log.i(LOGTAG, "EVENT_RECONNECT_FAILED");
                break;

            case Socket.EVENT_RECONNECTING:
                Log.i(LOGTAG, "EVENT_RECONNECTING");
                break;

            case IConstants.EVENT_RECEIVE_LOG:
                BroadcastUtil.sendBroadcastToUI(ctx,IConstants.EVENT_RECEIVE_LOG,args[0].toString());
                Log.i(LOGTAG,"------------"+args[0].toString());
                break;
            case IConstants.EVENT_START_LOG:
                C.START_SEND_LOG = true;
                Log.i(LOGTAG,"------------开启日志发送"+args[0].toString());
                break;
            case IConstants.EVENT_END_LOG:
                C.START_SEND_LOG = false;
                Log.i(LOGTAG,"------------结束日志发送"+args[0].toString());
                break;

        }
    }

    private static final long INITIALDELAY = 6;//初始化延时
    private static final long PERIOD = 6;//两次开始执行最小间隔时间
    private static final long AWAITTIME = 1;
    public void checkSocketConnectScheduledTask(){
        LOGSDKManager.getInstance().getCheckSocketConnectScheduler().scheduleWithFixedDelay(new CheckSocketConnectScheduledExecutor(ctx), INITIALDELAY,30, TimeUnit.SECONDS);
    }
    public void cancleCheckSocketConnectScheduledTask(){

        try {
            LOGSDKManager.getInstance().getCheckSocketConnectScheduler().shutdown();

            if(!LOGSDKManager.getInstance().getCheckSocketConnectScheduler().awaitTermination(AWAITTIME, TimeUnit.SECONDS)){
                // 超时的时候向线程池中所有的线程发出中断(interrupted)。
                LOGSDKManager.getInstance().getCheckSocketConnectScheduler().shutdownNow();
            }
        } catch (InterruptedException e) {
            // awaitTermination方法被中断的时候也中止线程池中全部的线程的执行。
            LOGSDKManager.getInstance().getCheckSocketConnectScheduler().shutdownNow();
        }
        Log.i(LOGTAG, "监控Socket连接任务结束----");

    }





    @Override
    public void requestSocketResult(String key, Object... args) {

    }

    private void openConnection(String url, String deviceNo) {
        initAppSocket(url,deviceNo);
    }
    /**
     * 初始化Socket
     */
    public void initAppSocket(String url, String deviceNo) {
        AppSocket.Builder builder;
        //builder = new AppSocket.Builder(url+ DeviceUtil.getDeviceId2Ipad(ctx)).setEmitterListener(this);
        builder = new AppSocket.Builder(url + deviceNo).setEmitterListener(this);
        AppSocket.init(builder).connect();
        C.CUR_SOCKET_URL = builder.socketHost;
    }
    public void closeConnection() {
        Log.i(LOGTAG, "closeConnection-------------");
        AppSocket.getInstance().disConnnect();
    }
    private void offEmitterListener() {
        Log.i(LOGTAG, "offEmitterListener------------- ");
        AppSocket.getInstance().offEmitterListener();
    }

    public void push_connect(String deviceNo) {
            openConnection(API_URL+"?deviceNo=",deviceNo);
    }

    public void stopConnection(){
        mHandler.removeCallbacksAndMessages(null);
        cancleCheckSocketConnectScheduledTask();
        C.START_SEND_LOG = false;
        closeConnection();
    }
}
